﻿#ifndef _FFMPG_STREAM_
#define _FFMPG_STREAM_

#include <Windows.h>
#include <WinBase.h>
#include "streaminfo.h"
#include "./sdl/include/SDL.h"
#include "thread.h"

class CCriticalSection
{
public:
	CCriticalSection()
	{
		::InitializeCriticalSection( &m_cs );
	}

	~CCriticalSection()
	{
		::LeaveCriticalSection( &m_cs );
	}

	void Enter()
	{
		::EnterCriticalSection( &m_cs );
	}

	void Leave()
	{
		::LeaveCriticalSection( &m_cs );
	}

protected:
	CRITICAL_SECTION m_cs;
};

//////////////////////////////////////////////////////////////////////////

#define LIMIT_AUDIO_QUEUESIZE		5 * 16 * 1024
#define LIMIT_VIDEO_QUEUESIZE		5 * 256 * 1024

typedef struct PacketQueue 
{
	AVPacketList *first_pkt;
	AVPacketList *last_pkt;
	int nb_packets;
	int size;
} PacketQueue;


class CStreamQueue : public CCriticalSection
{
public :
	CStreamQueue();
	~CStreamQueue();

	void	SetLimit(int limit) { m_limit = limit; }
	bool	PutdataToQueue(AVPacket *packet);
	int		GetdataFromQueue(AVPacket *packet);

private :
	int				m_limit;
	PacketQueue		m_queuedata;
};

//////////////////////////////////////////////////////////////////////////


class CStream : public CThread
{
public :
	CStreamQueue		m_Videoqueue;
	CStreamQueue		m_Audioqueue;

public :
	CStream();
	~CStream();


	bool	Open(char *file);
	void	Close();

	AVFrame*	GetAVFrame() { return m_pFrame; }
	void		RenderFrameToOverlay(SDL_Overlay *overlay);

	AVCodecContext *	GetAudio() { return	m_pAudioCodecCtx; }
	int			DecodeAudio(uint8_t *audio_buf, int buf_size);

	void	Run();

public :

	// Video info
	int					m_streamWidth;
	int					m_streamHeight;
	PixelFormat			m_streamFormat;

	// Audio info
	int					m_audioFreq;
	SampleFormat		m_audioFormat;
	int					m_audioChannels;
	int					m_audioSamples;


private :

	int			ReadFrame();
	bool		SearchStreams();
	bool		OpenCodec();
	void		OpenFrame();

	AVFormatContext *	m_pFormatCtx;

	// Video Codec
	int					m_videostream;
	char				m_videocodecname[64];
	int					m_videocodecid;
	AVCodecContext *	m_pVideoCodecCtx;
	AVCodec *			m_pVideoCodec;
	AVStream *			m_video_st;
	double				m_frame_timer;
	double				m_frame_last_delay;

	// Audio Codec
	int					m_audiostream;
	char				m_audiocodecname[64];
	int					m_audiocodecid;
	AVCodecContext *	m_pAudioCodecCtx;
	AVCodec *			m_pAudioCodec;
	AVStream *			m_audio_st;

	// Frame
	AVFrame*			m_pFrame; 
	AVPacket			m_AvPacket;

};



#endif